﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using WordNet.Core;
using WordNet.Core.ElementContracts;
using WordNet.Core.Extensions;

namespace WordNet.Core.Morphy
{
    // This stemmer adds functionality to the simple pattern-based stemmer
    // by checking to see if possible stems are actually contained in Wordnet.
    public class WordnetStemmer
    {
        private IWNDictionary dict;

        private IStemmer detacheRules;

        public WordnetStemmer()
        {
           dict =  WNDictionary.Container.GetExportedValue<IWNDictionary>();
           detacheRules = WNDictionary.Container.GetExportedValue<IStemmer>();
        }

        public IWNDictionary getDictionary()
        {
            return dict;
        }

        // finds stems that exist in WordNet; 
        // stems that cannot be found in WordNet are ignored
        public List<string> FindStems(string word, POS pos)
        {
            word = word.ToLower();
            word = word.WhitespaceToUnderscore();
            if (pos == null)
                return detacheRules.FindStems(word, null);

            List<String> result = new List<String>();

            // first look for the word in the exception lists
            IExceptionEntry excEntry = dict.GetExceptionEntry(word, pos);
            if (excEntry != null)
                result.AddRange(excEntry.GetRootForms());

            if (excEntry != null)
                return new List<String>(result);

            // then look and see if it's in Wordnet; if so, the form itself is a stem
            var temp = dict.FindWord(word, pos);
            if (temp != null)
            {
                result.Add(temp.Lemma);
                return result;
            }

            // go to the simple stemmer and check and see if any of those stems are in WordNet
            List<String> possibles = detacheRules.FindStems(word, pos);

            // check each algorithmically obtained root to see if it's in WordNet
            foreach (String possible in possibles)
            {
                if (dict.GetIndexWord(possible, pos) != null)
                    result.Add(possible);
            }

            if (result.Count() == 0)
                return new List<string>();

            return new List<String>(result);
        }
    }
}